﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.SOESupport;
using WorldViewSolutions.Geometry;

namespace WorldViewSolutions.ArcGISServer.SOE
{
    /// <summary>
    /// 
    /// </summary>
    /// <remarks></remarks>
    public static class GeometryUtilities
    {
        /// <summary>
        /// Froms the rest geometry.
        /// </summary>
        /// <param name="jo">The jo.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static WorldViewSolutions.Geometry.Geometry FromRestGeometry(JsonObject jo)
        {
            if (!jo.Exists("geometry")) return null;

            JsonObject geometry;
            if (!jo.TryGetJsonObject("geometry", out geometry)) return null;

            if (geometry.Exists("rings"))
                return FromRestPolygon(geometry);

            if (geometry.Exists("paths"))
                return FromRestPolyline(geometry);

            if (geometry.Exists("x") && geometry.Exists("y"))
                return FromRestPoint(geometry);

            return null;
        }

        /// <summary>
        /// Froms the rest point.
        /// </summary>
        /// <param name="jo">The jo.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Point FromRestPoint(JsonObject jo)
        {
            double? x, y;

            jo.TryGetAsDouble("x", out x);
            jo.TryGetAsDouble("y", out y);

            return new Point(x.Value, y.Value);
        }

        /// <summary>
        /// Froms the rest polyline.
        /// </summary>
        /// <param name="jo">The jo.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Polyline FromRestPolyline(JsonObject jo)
        {
            object[] pathArray;
            if (jo.TryGetArray("paths", out pathArray))
            {
                Polyline polyline = new Polyline();
                foreach (object[] pointArray in pathArray)
                {
                    Path path = FromRestPath(pointArray);
                    polyline.Paths.Add(path);
                }
                return polyline;
            }

            return null;
        }

        /// <summary>
        /// Froms the rest path.
        /// </summary>
        /// <param name="pointArray">The point array.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Path FromRestPath(object[] pointArray)
        {
            Path path = new Path();
            foreach (object[] p in pointArray)
            {
                Point point = new Point();
                point.X = Convert.ToDouble(p[0]);
                point.Y = Convert.ToDouble(p[1]);

                path.Points.Add(point);
            }
            return path;
        }


        /// <summary>
        /// Froms the rest polygon.
        /// </summary>
        /// <param name="jo">The jo.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Polygon FromRestPolygon(JsonObject jo)
        {
            object[] ringArray;
            if (jo.TryGetArray("rings", out ringArray))
            {
                Polygon polygon = new Polygon();
                foreach (object[] pointArray in ringArray)
                {
                    Ring ring = FromRestRing(pointArray);
                    polygon.Rings.Add(ring);
                }
                return polygon;
            }
            return null;
        }

        /// <summary>
        /// Froms the rest ring.
        /// </summary>
        /// <param name="pointArray">The point array.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Ring FromRestRing(object[] pointArray)
        {
            Ring ring = new Ring();

            foreach (object[] p in pointArray)
            {
                Point point = new Point();
                point.X = Convert.ToDouble(p[0]);
                point.Y = Convert.ToDouble(p[1]);

                ring.Points.Add(point);
            }
            return ring;           
        }
    }
}
